/*
 * This file is part of the <a href="http://code.google.com/p/pux">PUX Framework</a>
 *
 * Copyright 2008 by <a href="mailto:jfendler@polytechnic.edu.na">Jens Fendler</a>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package de.teamskill.pux.library.image;

import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.LookupOp;
import java.awt.image.ShortLookupTable;
import java.util.Arrays;

import de.teamskill.pux.engine.InputPort;
import de.teamskill.pux.engine.OutputPort;

/**
 * RGBSplitNode
 * 
 * @author <a href="mailto:jfendler@polytechnic.edu.na">Jens Fendler</a>
 * 
 */
public class RGBSplitNode extends AbstractImageFilter {

	/**
	 * red
	 */
	private OutputPort red;

	/**
	 * green
	 */
	private OutputPort green;

	/**
	 * blue
	 */
	private OutputPort blue;

	/**
	 * alpha
	 */
	private OutputPort alpha;

	/**
	 * type1
	 */
	private InputPort type1;

	/**
	 * type2
	 */
	private InputPort type2;

	/**
	 * RGBSplitNode Constructor
	 * 
	 */
	public RGBSplitNode() {
		this("RGBSPLIT" + nr++, false);
	}

	/**
	 * RGBSplitNode Constructor
	 * 
	 * @param nodeName
	 * @param continuous
	 */
	public RGBSplitNode(String nodeName, boolean continuous) {
		super(nodeName, continuous);
	}

	/**
	 * @see de.teamskill.pux.engine.AbstractNode#compute()
	 */
	public void compute() {
		BufferedImage bi = (BufferedImage) in.fetchData();

		short[] copy = new short[256];
		for (int i = 0; i < copy.length; copy[i] = (short) i++)
			;
		short[] strip = new short[256];
		Arrays.fill(strip, (short) 0);

		int t1 = (Integer) type1.fetchData();
		int t2 = (Integer) type2.fetchData();

		ColorConvertOp op = new ColorConvertOp(null);
		BufferedImage tmpR = new BufferedImage(bi.getWidth(), bi.getHeight(), t1);
		BufferedImage tmpG = new BufferedImage(bi.getWidth(), bi.getHeight(), t1);
		BufferedImage tmpB = new BufferedImage(bi.getWidth(), bi.getHeight(), t1);
		BufferedImage tmpA = new BufferedImage(bi.getWidth(), bi.getHeight(), t1);

		BufferedImage r = new BufferedImage(bi.getWidth(), bi.getHeight(), t2);
		new LookupOp(new ShortLookupTable(0, new short[][] { copy, strip, strip, copy }), null).filter(bi, r);
		red.pushData(op.filter(r, tmpR));

		BufferedImage g = new BufferedImage(bi.getWidth(), bi.getHeight(), t2);
		new LookupOp(new ShortLookupTable(0, new short[][] { strip, copy, strip, copy }), null).filter(bi, g);
		green.pushData(op.filter(g, tmpG));

		BufferedImage b = new BufferedImage(bi.getWidth(), bi.getHeight(), t2);
		new LookupOp(new ShortLookupTable(0, new short[][] { strip, strip, copy, copy }), null).filter(bi, b);
		blue.pushData(op.filter(b, tmpB));

		BufferedImage a = new BufferedImage(bi.getWidth(), bi.getHeight(), t2);
		new LookupOp(new ShortLookupTable(0, new short[][] { strip, strip, strip, copy }), null)
				.filter(bi, a);
		alpha.pushData(op.filter(a, tmpA));
	}

	/**
	 * @see de.teamskill.pux.library.image.AbstractImageFilter#createPorts()
	 */
	protected void createPorts() {
		in = addInputPort(new InputPort("IN", this, true, BufferedImage.class));
		red = addOutputPort(new OutputPort("RED", this, BufferedImage.class));
		green = addOutputPort(new OutputPort("GREEN", this, BufferedImage.class));
		blue = addOutputPort(new OutputPort("BLUE", this, BufferedImage.class));
		alpha = addOutputPort(new OutputPort("ALPHA", this, BufferedImage.class));
		type1 = addConfigurationPort("imageType1", Integer.class, new Integer(BufferedImage.TYPE_BYTE_GRAY));
		type2 = addConfigurationPort("imageType2", Integer.class, new Integer(
				BufferedImage.TYPE_4BYTE_ABGR_PRE));
	}

	/**
	 * JavaBean-style getter-method for red
	 * 
	 * @return the red
	 */
	public OutputPort getRed() {
		return red;
	}

	/**
	 * /** JavaBean-style setter-method for red
	 * 
	 * @param red
	 *            the red to set
	 */
	public void setRed(OutputPort red) {
		this.red = red;
	}

	/**
	 * JavaBean-style getter-method for green
	 * 
	 * @return the green
	 */
	public OutputPort getGreen() {
		return green;
	}

	/**
	 * /** JavaBean-style setter-method for green
	 * 
	 * @param green
	 *            the green to set
	 */
	public void setGreen(OutputPort green) {
		this.green = green;
	}

	/**
	 * JavaBean-style getter-method for blue
	 * 
	 * @return the blue
	 */
	public OutputPort getBlue() {
		return blue;
	}

	/**
	 * /** JavaBean-style setter-method for blue
	 * 
	 * @param blue
	 *            the blue to set
	 */
	public void setBlue(OutputPort blue) {
		this.blue = blue;
	}

	/**
	 * JavaBean-style getter-method for alpha
	 * 
	 * @return the alpha
	 */
	public OutputPort getAlpha() {
		return alpha;
	}

	/**
	 * /** JavaBean-style setter-method for alpha
	 * 
	 * @param alpha
	 *            the alpha to set
	 */
	public void setAlpha(OutputPort alpha) {
		this.alpha = alpha;
	}

}
